#include "osal/string.h"
#include "custom_mem/custom_mem.h"
#include "stream_frame.h"
#include "osal/task.h"
#include "dev/usb/uvc_host.h"
#include "osal/task.h"

#define AUDIO_LEN  (1024)
struct os_task get_usbmic_audio_task;

static uint32_t get_sound_data_len(void *data)
{
    struct data_structure  *d = (struct data_structure  *)data;
	return (uint32_t)d->priv;
}
static uint32_t set_sound_data_len(void *data,uint32_t len)
{
	struct data_structure  *d = (struct data_structure  *)data;
	d->priv = (void*)len;
	return len;
}
static stream_ops_func stream_sound_ops = 
{
	.get_data_len = get_sound_data_len,
	.set_data_len = set_sound_data_len,
};

static int opcode_func(stream *s,void *priv,int opcode)
{
	static uint8 *audio_buf = NULL;
	int res = 0;
	switch(opcode)
	{
		case STREAM_OPEN_ENTER:
		break;
		case STREAM_OPEN_EXIT:
		{			
			audio_buf = os_malloc(4 * AUDIO_LEN);
			if(audio_buf)
			{
				stream_data_dis_mem(s,4);
			}
			streamSrc_bind_streamDest(s,R_USB_SPK);	
		}
		break;
		case STREAM_OPEN_FAIL:
		break;

		case STREAM_FILTER_DATA:
		break;

		case STREAM_DATA_DIS:
		{
			struct data_structure *data = (struct data_structure *)priv;
			int data_num = (int)data->priv;
			data->ops = &stream_sound_ops;
			data->data = audio_buf + (data_num)*AUDIO_LEN;
		}
		break;

		case STREAM_DATA_FREE:
			//_os_printf("%s:%d\n",__FUNCTION__,__LINE__);
		break;


		//数据发送完成,可以选择唤醒对应的任务
		case STREAM_RECV_DATA_FINISH:
		break;

		default:
			//默认都返回成功
		break;
	}
	return res;	
}

extern int get_audio_dac_set_filter_type(void);
extern void audio_dac_set_filter_type(int filter_type);
int get_usbmic_audio(void *d)
{

	struct data_structure *data = NULL;
    volatile int16 *realdata = NULL;
	int former_dac_priv = 0;
    int16 *audio_addr = NULL;
	uint32 audio_len = 0;
	UAC_MANAGE *usbmic_manage = NULL;
	stream *src = open_stream_available(S_USB_MIC, 4, 0, opcode_func,NULL);

	if(!src)
	{
		os_printf("\nopen usbmic stream err");
		return 0;
	}
	former_dac_priv = get_audio_dac_set_filter_type();
	audio_dac_set_filter_type(SOUND_MIC);
	while(1)
	{
		data = get_src_data_f(src);
		if(data)
		{
			usbmic_manage = get_usbmic_frame();
			if(usbmic_manage)
			{
				audio_len = get_uac_frame_datalen(usbmic_manage);
				audio_addr = (int16*)get_uac_frame_data(usbmic_manage);
				realdata = get_stream_real_data(data);
				os_memcpy(realdata, audio_addr, audio_len);
				del_usbmic_frame(usbmic_manage);
				data->type = SET_DATA_TYPE(SOUND, SOUND_MIC);
				set_stream_real_data_len(data,audio_len);
				send_data_to_stream(data);
			}
			else
			{
				force_del_data(data);
			}
		}
		os_sleep_ms(10);
	}
	return 0;
}

void usbmic_audio_init(void)
{
	static uint8 usbmic_init_flag = 0;
	if(usbmic_init_flag == 0) {
		OS_TASK_INIT("get_usbmic_audio", &get_usbmic_audio_task, get_usbmic_audio, NULL, OS_TASK_PRIORITY_NORMAL, 512);
		usbmic_init_flag = 1;
		usbmic_room_init();
	}
}
